<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*
            基本数据类型里的比较
               比较运算： 如果是不同类型，才会进行隐式转换，并且都是转成数字进行比较
        */

      // console.log( 1 == true ) // true
      // console.log( 0 == false ) // true
      // console.log( '1' == 1 ) // true
      // console.log( 'a' == 1 ) // false

      // // 实际上这里比较的是 NaN == 1
      // console.log('true' == true)  // false
      // // 实际上这里比较的是 NaN == 0
      // console.log('false' == false) // false

      // 在其他地方，特别是要做判断真假的位置，那都是隐式转换成布尔类型
      // if ('true') {
      //     alert('1')
      // }
      // if('false') {
      //     alert('2')
      // }
      // 'false' && alert(3)

      // 字符串false隐式转换成true
      // 'false' ? alert('a') : alert('b')

      /*
            复杂类型之间==比较，都是比较的地址

            每当遇到
                {}、 []、 function，其实都会开辟新的堆空间
            因为 {} 其实相当于是 new Object() 的缩写
            因为 [] 其实相当于是 new Array() 的缩写
            function 相当于是 new Function() 的缩写
        */

      //    console.log( {} == {} ) // false
      //    console.log( [] == [] ) // false
      //    console.log( [10,20,30] == [10,20,30] ) // false

      //    const arr1 = [10,20,30]
      //    const arr2 = arr1
      //    console.log(arr1 == arr2) // true

      /*
        如果一个是基本类型，一个是复杂类型呢？
            会先把复杂类型调用 `valueOf`,如果没有valueOf,就调用`toString`转成基本数据类型后
            再按照基本数据类型的规则进行比较

        有valueOf的只有三种复杂类型：基本包装类型： Number、String、Boolean
    */
      //  console.log({}.toString())

      // 相当于比较的是 'a' == '[object Object]'
      // console.log('a' == {} ) // false

      // 相当于比较的就是 '[object Object]' == '[object Object]'
      // console.log('[object Object]' == {} ) // true

      // 全等：类型不一样就false了
      // console.log('[object Object]' === {} ) // false

      // 一个复杂类型和一个基本类型，调用复杂类型的toString
      //   console.log([10].toString()) // '10'
      //   console.log([10, 20].toString()) // '10,20'
      //   console.log([10, 20, 30].toString()) // '10,20,30'

      //  // 比较的就是 '10' == '10'
      //   console.log( '10' == [10] ) // true
      //  // 比较的就是 '1020' == '10,20'
      //   console.log('1020' == [10, 20]) // false

      // 10 == '10'  转成 10 == 10
      // console.log(10 == [10])   // true
      // console.log(10 == ['10']) // true

      // 0 == '' 空字符串转成数字是0 所以 0 == 0
      // console.log(0 == []) // true

      // 根据优先级先算逻辑非
      // ![]进行取反，那会先把[]转成布尔类型，[]不属于那五种情况，所以转成true
      // 对true取反得到 false 相当于在比较 false == []
      // 这时候才进行比较 false == ''  根据不同的基本数据类型比较，会转成数字
      // 0 == 0
      // console.log( ![] == [] ) // true

      // // false == {}
      // // false == '[object Object]'
      // // 0 == NaN
      // console.log( !{} == {} ) // false

      // const arr = [
      //     x => x * 1,
      //     x => x * 2,
      //     x => x * 3,
      //     x => x * 4
      // ]

      // console.log(arr.reduce((agg, el) => agg + el(agg), 0))

      // 技巧就是看函数有没有写return，没什么return什么都不用看，直接给undefined
      /*
        var x = 1
        var y = 0
        var z = 0

        function add (n) {
            n = n + 1
        }

        y = add(x)

        function add (n) {
            n = n + 3
        }
        z = add(x)

        s = y + z 


        console.log(y, z, s) // undefined undefined NaN
    */
    
    /*
      var x = 1
      var y = 0
      var z = 0

      function add (n) {
        return n = n + 1
      }

      y = add(x)

      function add (n) {
        return n = n + 3
      }
      z = add(x)
      s = y + z
      console.log(y, z, s) // 
    */
    </script>
  </body>
</html>
